package com.hyt.it.ogt.kq.common.bm.utils;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Random;

import com.hyt.core.util.DateUtils;
import com.hyt.it.ogt.kq.common.utils.KqStringUtils;

import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateBetween;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.lang.Assert;

/**
 * 日期处理工具类
 */
public class DateUtil {

	public static final String YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
	public static final String HH_MM = "HH:mm";

	/**
	 * 将TimeStamp的字符串解析成Date字符串
	 * @param dateString
	 * @return
	 */
	public static String getStringFormatTimeStamp(String dateString) {
		try {
			Date date = DateUtils.parseDatetime(dateString, YYYY_MM_DD_HH_MM_SS_SSS);
			return DateUtils.formatDatetime(date);
		} catch (Exception e) {
			return dateString;
		}
	}

	/**
	 * 获取现在时间
	 *
	 * @return 返回时间类型 yyyy-MM-dd HH:mm:ss
	 */
	public static Date getNowDate() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = formatter.format(currentTime);
		ParsePosition pos = new ParsePosition(0);
		Date currentTime_2 = formatter.parse(dateString, pos);
		return currentTime_2;
	}

	/**
	 * 获取现在时间
	 *
	 * @return 返回短时间格式 yyyy-MM-dd
	 */
	public static Date getNowDateShort() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = formatter.format(currentTime);
		ParsePosition pos = new ParsePosition(10);
		Date currentTime_2 = formatter.parse(dateString, pos);
		return currentTime_2;
	}

	/**
	 * 获取现在时间
	 *
	 * @return 返回字符串格式 yyyy-MM-dd HH:mm:ss
	 */
	public static String getStringDate() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = formatter.format(currentTime);
		return dateString;
	}

	/**
	 * 获取现在时间
	 *
	 * @return 返回字符串格式 yyyy-MM-dd HH:mm:ss
	 */
	public static String getStringDateLong() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		String dateString = formatter.format(currentTime);
		return dateString;
	}

	/**
	 * 获取现在时间
	 *
	 * @return 返回短时间字符串格式yyyy-MM-dd
	 */
	public static String getStringDateShort() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = formatter.format(currentTime);
		return dateString;
	}

	/**
	 * 获取现在时间
	 *
	 * @return 返回短时间字符串格式yyyyMMdd
	 */
	public static String getJcbhDateShort() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
		String dateString = formatter.format(currentTime);
		return dateString;
	}

	/**
	 * 获取时间 小时:分;秒 HH:mm:ss
	 *
	 * @return HH:mm:ss
	 */
	public static String getTimeShort() {
		SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
		Date currentTime = new Date();
		String dateString = formatter.format(currentTime);
		return dateString;
	}

	/**
	 * 获取时间 小时:分;秒 HH:mm:ss
	 *
	 * @return yyyyMMddHHmmss
	 */
	public static String getTimeAll() {
		SimpleDateFormat formatter = new SimpleDateFormat(YYYYMMDDHHMMSS);
		Date currentTime = new Date();
		String dateString = formatter.format(currentTime);
		return dateString;
	}

	/**
	 * 将长时间格式字符串转换为时间 yyyy-MM-dd HH:mm:ss
	 *
	 * @param strDate 日期
	 * @return 格式化yyyy-MM-dd HH:mm:ss，Date格式
	 */
	public static Date strToDateLong(String strDate) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		ParsePosition pos = new ParsePosition(0);
		Date strtodate = formatter.parse(strDate, pos);
		return strtodate;
	}

	/**
	 * 将长时间格式字符串转换为时间 yyyy-MM-dd HH:mm:ss
	 *
	 * @param strDate 日期
	 * @return 格式化yyyy-MM-dd HH:mm:ss.SSS, Date格式
	 */
	public static Date strHmToDateLong(String strDate) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		ParsePosition pos = new ParsePosition(0);
		Date strtodate = formatter.parse(strDate, pos);
		return strtodate;
	}

	/**
	 * 将长时间格式时间转换为字符串 yyyy-MM-dd HH:mm:ss
	 *
	 * @param dateDate 日期Date
	 * @return yyyy-MM-dd HH:mm:ss
	 */
	public static String dateToStrLong(Date dateDate) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = formatter.format(dateDate);
		return dateString;
	}

	/**
	 * 将长时间格式时间转换为字符串 HH:mm:ss
	 *
	 * @param dateDate 日期Date
	 * @return yyyy-MM-dd HH:mm:ss
	 */
	public static String dateToStrLongHHmmss(Date dateDate) {
		SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
		String dateString = formatter.format(dateDate);
		return dateString;
	}

	/**
	 * 将短时间格式时间转换为字符串 yyyy-MM-dd
	 *
	 * @param dateDate 日期Date
	 * @return yyyy-MM-dd
	 */
	public static String dateToStr(Date dateDate) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = formatter.format(dateDate);
		return dateString;
	}

	/**
	 * 将短时间格式时间转换为字符串 yyyyMMdd
	 *
	 * @param dateDate 日期Date
	 * @return yyyyMMdd
	 */
	public static String dateToStrF(Date dateDate) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
		String dateString = formatter.format(dateDate);
		return dateString;
	}

	/**
	 * 将短时间格式字符串转换为时间 yyyy-MM-dd
	 *
	 * @param strDate Date
	 * @return 格式化yyyy-MM-dd，Date类型
	 */
	public static Date strToDate(String strDate) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		ParsePosition pos = new ParsePosition(0);
		Date strtodate = formatter.parse(strDate, pos);
		return strtodate;
	}

	/**
	 * 指定format将字符串装成date
	 *
	 * @param strDate
	 * @param formate
	 * @return String
	 */
	public static Date strToDate(String strDate, String formate) {
		SimpleDateFormat formatter = new SimpleDateFormat(formate);
		ParsePosition pos = new ParsePosition(0);
		Date strtodate = formatter.parse(strDate, pos);
		return strtodate;
	}

	/**
	 * 得到现在时间
	 *
	 * @return Date
	 */
	public static Date getNow() {
		Date currentTime = new Date();
		return currentTime;
	}

	/**
	 * 提取一个月中的最后一天
	 *
	 * @param day
	 * @return date
	 */
	public static Date getLastDate(long day) {
		Date date = new Date();
		long date_3_hm = date.getTime() - 3600000 * 34 * day;
		Date date_3_hm_date = new Date(date_3_hm);
		return date_3_hm_date;
	}

	/**
	 * 得到现在时间
	 *
	 * @return 字符串 yyyyMMdd HHmmss
	 */
	public static String getStringToday() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd HHmmss");
		String dateString = formatter.format(currentTime);
		return dateString;
	}

	/**
	 * 得到现在小时
	 *
	 * @return HH
	 */
	public static String getHour() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = formatter.format(currentTime);
		String hour;
		hour = dateString.substring(11, 13);
		return hour;
	}

	/**
	 * 得到现在分钟
	 *
	 * @return mm
	 */
	public static String getTime() {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = formatter.format(currentTime);
		String min;
		min = dateString.substring(14, 16);
		return min;
	}

	/**
	 * 根据用户传入的时间表示格式，返回当前时间的格式 如果是yyyyMMdd，注意字母y不能大写。
	 * dateUtil.getUserDate("yyyy-MM-dd HH:mm:ss:SSS")
	 *
	 * @param sformat yyyyMMddhhmmss
	 * @return 格式化后的时间 2018-03-05 09:02:09:398
	 */
	public static String getUserDate(String sformat) {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat(sformat);
		String dateString = formatter.format(currentTime);
		return dateString;
	}

	/**
	 * @param st1
	 * @param st2 二个小时时间间的差值,必须保证二个时间都是"HH:mm"的格式，返回字符型的分钟
	 * @return String
	 */
	public static String getTwoHour(String st1, String st2) {
		long bTime = strToDate(st1, "HH:mm").getTime();
		long eTime = strToDate(st2, "HH:mm").getTime();
		long abs = Math.abs((bTime - eTime) / 1000 / 60);
		return abs + "";
	}

	/**
	 * @param sj1
	 * @param sj2 得到二个日期间的间隔天数
	 * @return String
	 */
	public static String getTwoDay(String sj1, String sj2) {
		SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
		long day = 0;
		try {
			Date date = myFormatter.parse(sj1);
			Date mydate = myFormatter.parse(sj2);
			day = Math.abs(date.getTime() - mydate.getTime()) / (24 * 60 * 60 * 1000) + 1;
		} catch (Exception e) {
			return "";
		}
		return day + "";
	}

	/**
	 * @param date1
	 * @param date2 得到二个日期间的间隔月份
	 * @return String
	 * @exception ParseException
	 */
	public static int getMonthSpace(String date1, String date2) throws ParseException {

		int result = 0;

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();

		c1.setTime(format.parse(date1));
		c2.setTime(format.parse(date2));

		result = (c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR)) * 12 + c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);

		return result;
	}

	/**
	 * @param sj1
	 * @param jj  时间前推或后推分钟,其中JJ表示分钟.
	 * @return string
	 */
	public static String getPreTime(String sj1, String jj) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String mydate1 = "";
		try {
			Date date1 = format.parse(sj1);
			long Time = (date1.getTime() / 1000) + Integer.parseInt(jj) * 60;
			date1.setTime(Time * 1000);
			mydate1 = format.format(date1);
		} catch (Exception e) {

		}
		return mydate1;
	}

	/**
	 * 将一个时间推迟或提前N分钟，返回指定格式的字符串
	 *
	 * @param date
	 * @param myFormat
	 * @param preTime
	 * @return string
	 */
	public static String getPreTimeByFormat(Date date, String myFormat, int preTime) {
		long time = (date.getTime() / 1000) + preTime * 60;
		Date d = new Date(time);
		SimpleDateFormat format = new SimpleDateFormat(myFormat);
		return format.format(d);
	}

	/**
	 * @param nowdate
	 * @param delay   得到一个时间延后或前移几天的时间,nowdate为时间,delay为前移或后延的天数
	 * @return string
	 */
	public static String getNextDay(String nowdate, String delay) {
		try {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			String mdate = "";
			Date d = strToDate(nowdate);
			long myTime = (d.getTime() / 1000) + Integer.parseInt(delay) * 24 * 60 * 60;
			d.setTime(myTime * 1000);
			mdate = format.format(d);
			return mdate;
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * @param str 返回美国时间格式 26 Apr 2006
	 * @return string
	 */
	public static String getEDate(String str) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		ParsePosition pos = new ParsePosition(0);
		Date strtodate = formatter.parse(str, pos);
		String j = strtodate.toString();
		String[] k = j.split(" ");
		return k[2] + k[1].toUpperCase() + k[5].substring(2, 4);
	}

	/**
	 * @param date1
	 * @param date2 判断二个时间是否在同一个周
	 * @return boolean
	 */
	public static boolean isSameWeekDates(Date date1, Date date2) {
		Calendar cal1 = Calendar.getInstance();
		Calendar cal2 = Calendar.getInstance();
		cal1.setTime(date1);
		cal2.setTime(date2);
		int subYear = cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR);
		if (0 == subYear) {
			if (cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR)) {
				return true;
			}
		} else if (1 == subYear && 11 == cal2.get(Calendar.MONTH)) {
			// 如果12月的最后一周横跨来年第一周的话则最后一周即算做来年的第一周
			if (cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR)) {
				return true;
			}
		} else if (-1 == subYear && 11 == cal1.get(Calendar.MONTH)) {
			if (cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 产生周序列,即得到当前时间所在的年度是第几周
	 *
	 * @return String
	 */
	public static String getSeqWeek() {
		Calendar c = Calendar.getInstance(Locale.CHINA);
		String week = Integer.toString(c.get(Calendar.WEEK_OF_YEAR));
		if (week.length() == 1) {
			week = "0" + week;
		}
		String year = Integer.toString(c.get(Calendar.YEAR));
		return year + week;
	}

	/**
	 * @param sdate 根据一个日期，返回是星期几的字符串
	 * @return string
	 */
	public static String getWeek(String sdate) {
		// 再转换为时间
		Date date = DateUtil.strToDate(sdate);
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		// int hour=c.get(Calendar.DAY_OF_WEEK);
		// hour中存的就是星期几了，其范围 1~7
		// 1=星期日 7=星期六，其他类推
		return new SimpleDateFormat("EEEE").format(c.getTime());
	}

	/**
	 * 输入数字1，返回对应的星期一
	 *
	 * @param sdate 1-7
	 * @return "星期日"
	 */
	public static String getWeekStr(String sdate) {
		String str = "";
		str = DateUtil.getWeek(sdate);
		if ("7".equals(str)) {
			str = "星期日";
		} else if ("1".equals(str)) {
			str = "星期一";
		} else if ("2".equals(str)) {
			str = "星期二";
		} else if ("3".equals(str)) {
			str = "星期三";
		} else if ("4".equals(str)) {
			str = "星期四";
		} else if ("5".equals(str)) {
			str = "星期五";
		} else if ("6".equals(str)) {
			str = "星期六";
		}
		return str;
	}

	/**
	 * @param date1
	 * @param date2 两个时间之间的天数
	 * @return long
	 */
	public static long getDays(String date1, String date2) {
		if (date1 == null || date1.equals("") || date2 == null || date2.equals("")) {
			return 0;
		}
		// 转换为标准时间
		SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
		Date date = null;
		Date mydate = null;
		try {
			date = myFormatter.parse(date1);
			mydate = myFormatter.parse(date2);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
		long day = (date.getTime() - mydate.getTime()) / (24 * 60 * 60 * 1000);
		return day;
	}

	/**
	 * @param date1
	 * @param date2 两个时间之间的天数
	 * @return long
	 */
	public static long getDays(Date date1, Date date2) {
		if (date1 == null) {
			return 0;
		}
		if (date2 == null) {
			return 0;
		}
		long day = (date1.getTime() - date2.getTime()) / (24 * 60 * 60 * 1000);
		return day;
	}

	/**
	 * @param sdate 形成如下的日历 ， 根据传入的一个时间返回一个结构 星期日 星期一 星期二 星期三 星期四 星期五 星期六 下面是当月的各个时间
	 *              此函数返回该日历第一行星期日所在的日期
	 * @return string
	 */
	public static String getNowMonth(String sdate) {
		// 取该时间所在月的一号
		sdate = sdate.substring(0, 8) + "01";

		// 得到这个月的1号是星期几
		Date date = DateUtil.strToDate(sdate);
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int u = c.get(Calendar.DAY_OF_WEEK);
		String newday = DateUtil.getNextDay(sdate, (1 - u) + "");
		return newday;
	}

	/**
	 * 取得数据库主键 生成格式为yyyymmddhhmmss+k位随机数
	 *
	 * @param k 表示是取几位随机数，可以自己定
	 * @return string
	 * @throws NoSuchAlgorithmException 
	 */

	public static String getNo(int k) throws NoSuchAlgorithmException {
		return getUserDate("yyyyMMddhhmmss") + getRandom(k);
	}

	/**
	 * 按指定格式加指定位数随机数产生主键
	 *
	 * @param format
	 * @param k
	 * @return String
	 * @throws NoSuchAlgorithmException 
	 */
	public static String getNoByFormat(String format, int k) throws NoSuchAlgorithmException {
		return getUserDate(format) + getRandom(k);
	}

	/**
	 *
	 * 返回一个随机数
	 *
	 * @param i
	 * @return String
	 * @throws NoSuchAlgorithmException 
	 */
	public static String getRandom(int i) throws NoSuchAlgorithmException {
		Random rand = SecureRandom.getInstanceStrong();
		// int suiJiShu = jjj.nextInt(9);
		if (i == 0) {
			return "";
		}
		String jj = "";
		for (int k = 0; k < i; k++) {
			jj = jj + rand.nextInt(9);
		}
		return jj;
	}

	/**
	 * @param date 判断是否是正确的时间格式
	 * @return boolean
	 */
	public static boolean isRightDate(String date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		if (date == null) {
			return false;
		}
		if (date.length() > 10) {
			sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		} else {
			sdf = new SimpleDateFormat("yyyy-MM-dd");
		}
		try {
			sdf.parse(date);
		} catch (ParseException pe) {
			return false;
		}
		return true;
	}

	/**
	 * 比较两个日期的大小
	 *
	 * @param DATE1
	 * @param DATE2
	 * @return dt1 在dt2前 返回1，dt1在dt2后 返回-1
	 * @exception exception
	 */
	public static int compare_date(String DATE1, String DATE2) {

		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date dt1 = df.parse(DATE1);
			Date dt2 = df.parse(DATE2);
			if (dt1.getTime() > dt2.getTime()) {
				return 1;
			} else if (dt1.getTime() < dt2.getTime()) {
				return -1;
			}
		} catch (Exception exception) {
			exception.printStackTrace();
		}
		return 0;
	}

	/**
	 * 将CST格式字符串时间转换为时间 yyyy-MM-dd
	 *
	 * @param strDate
	 * @return Date
	 */
	public static Date strCSTToDate(String strDate) {
		SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss 'CST' yyyy", Locale.US);
		ParsePosition pos = new ParsePosition(0);
		Date date = sdf.parse(strDate, pos);

		return date;
	}

	/**
	 * 将CST格式字符串时间转换为 yyyy-MM-dd 时间格式字符串
	 *
	 * @param strDate
	 * @return String
	 */
	public static String strCSTToStr(String strDate) {
		Date date = strCSTToDate(strDate);
		String str = dateToStr(date);
		return str;
	}

	/**
	 * @param st1
	 * @param st2 二个小时时间间的差值,必须保证二个时间都是"HH:MM"的格式，返回字符型的分钟
	 * @return String
	 */
	public static String getTwoMinute(String st1, String st2) {
		String[] kk = null;
		String[] jj = null;
		kk = st1.split(":");
		jj = st2.split(":");

		double y = Double.parseDouble(kk[0]) * 60 + Double.parseDouble(kk[1]);
		double u = Double.parseDouble(jj[0]) * 60 + Double.parseDouble(jj[1]);
		if ((y - u) > 0) {
			return y - u + "";
		} else {
			return u - y + "";
		}

	}

	/**
	 * 二个日期时间间的差值,必须保证二个时间都是同一天的长时间格式(不判断隔天的)，返回字符型的分钟
	 *
	 * @param st1 yyyy-MM-dd hh:mm:ss
	 * @param st2 yyyy-MM-dd hh:mm:ss
	 * @return String
	 */
	public static String getTwoMinuteBydate(String st1, String st2) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		// 计算时间间隔
		try {
			Date startTime = sdf.parse(st1);
			Date endTime = sdf.parse(st2);
			long minute = Math.abs(endTime.getTime() - startTime.getTime()) / (60 * 1000) + 1;
			return minute + "";
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "0";
	}

	/**
	 * 日期 天数加减
	 *
	 * @param currentDay
	 * @param day
	 * @return string
	 * @exception ParseException
	 */
	public static String dayAddAndSub(String currentDay, int day) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date dt = sdf.parse(currentDay);
		Calendar rightNow = Calendar.getInstance();
		rightNow.setTime(dt);
		rightNow.add(Calendar.DAY_OF_YEAR, day); // 日期加 [day] 天
		return sdf.format(rightNow.getTime());
	}

	/**
	 * 分钟 加减
	 *
	 * @param currentDay
	 * @param minute
	 * @return string
	 * @exception ParseException
	 */
	public static String minuteAddAndSub(String currentDay, int minute) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date dt = sdf.parse(currentDay);
		Calendar rightNow = Calendar.getInstance();
		rightNow.setTime(dt);
		rightNow.add(Calendar.MINUTE, minute);
		return sdf.format(rightNow.getTime());
	}

	/**
	 * 秒 加减
	 *
	 * @param currentDay
	 * @param second
	 * @return String
	 * @exception ParseException
	 */
	public static String secondAddAndSub(String currentDay, int second) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date dt = sdf.parse(currentDay);
		Calendar rightNow = Calendar.getInstance();
		rightNow.setTime(dt);
		rightNow.add(Calendar.SECOND, second);
		return sdf.format(rightNow.getTime());
	}

	/**
	 * 获取该日期所在月份的天数
	 *
	 * @param currentDay
	 * @return int
	 * @throws ParseException
	 */
	public static int monthDay(String currentDay) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date dt = sdf.parse(currentDay);
		Calendar rightNow = Calendar.getInstance();
		rightNow.setTime(dt);
		rightNow.getActualMaximum(Calendar.DAY_OF_MONTH);
		return rightNow.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 格式化日期
	 *
	 * @param date
	 * @param format
	 * @return String
	 */
	public static String formatDateByFormat(Date date, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date);
	}

	/**
	 * 格式化日期
	 *
	 * @param format
	 * @return String
	 */
	public static String getDateByFormat(String format) {
		Date currentTime = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		return formatter.format(currentTime);
	}

	/**
	 * 获取两个日期之间的日期列表
	 *
	 * @param startDate
	 * @param endDate
	 * @return list
	 */
	public static List<String> getDayList(Date startDate, Date endDate) {
		List<String> result = new ArrayList<String>();
		Calendar tempStart = Calendar.getInstance();
		tempStart.setTime(startDate);
		Calendar tempEnd = Calendar.getInstance();
		tempEnd.setTime(endDate);
		if (startDate.equals(endDate)) {
			result.add(dateToStr(tempStart.getTime()));
			return result;
		}
		while (!tempStart.after(tempEnd)) {
			result.add(dateToStr(tempStart.getTime()));
			tempStart.add(Calendar.DAY_OF_YEAR, 1);
		}
		return result;
	}

	/**
	 * 获取两个时间中间的分钟列表
	 *
	 * @param startDate
	 * @param endDate
	 * @param noTail
	 * @return List
	 */
	public static List<String> getMinuteList(Date startDate, Date endDate, boolean noTail) {
		List<String> result = new ArrayList<String>();
		Calendar tempStart = Calendar.getInstance();
		tempStart.setTime(startDate);
		Calendar tempEnd = Calendar.getInstance();
		tempEnd.setTime(endDate);
		while (!tempStart.after(tempEnd)) {
			result.add(formatDateByFormat(tempStart.getTime(), "HH:mm"));
			tempStart.add(Calendar.MINUTE, 1);
		}
		if (noTail) {
			// 如果不要尾巴，就移除掉最后一个元素
			result.remove(result.size() - 1);
		}
		return result;
	}


	/**
	 * 判断一组时间区间是否交叉
	 *
	 * @param list
	 * @param split
	 * @return boolean
	 */
	public static boolean checkOverlap(List<String> list, String split) {
		Collections.sort(list); // 排序ASC
		boolean flag = false; // 是否重叠标识
		for (int i = 0; i < list.size(); i++) {
			if (i > 0) {
				// 跳过第一个时间段不做判断
				String[] itime = list.get(i).split(split);
				for (int j = 0; j < list.size(); j++) {
					// 如果当前遍历的i开始时间小于j中某个时间段的结束时间那么则有重叠，反之没有重叠
					// 这里比较时需要排除i本身以及i之后的时间段，因为已经排序了所以只比较自己之前(不包括自己)的时间段
					if (j == i || j > i) {
						continue;
					}
					String[] jtime = list.get(j).split(split);
					if (strToDate(itime[0], "HH:mm").before(strToDate(jtime[1], "HH:mm"))) {
						flag = true;
						break; // 只要存在一个重叠则可退出内循环
					}
				}
			}
			// 当标识已经认为重叠了则可退出外循环
			if (flag) {
				break;
			}
		}
		return flag;
	}

	/**
	 * 把日期和时间匹配起来，形成多段区间
	 *
	 * @param days
	 * @param useableTimeSection
	 * @return list
	 */
	public static List<String> getUseableDateTimeSection(List<String> days, List<String> useableTimeSection) {
		List<String> result = new ArrayList<String>();
		for (String day : days) {
			for (String timeSection : useableTimeSection) {
				result.add(day + "|" + timeSection);
			}
		}
		Collections.sort(result);
		return result;
	}

	/**
	 * 将String格式转为日期格式,格式为：2017-08-08 12:12:12
	 *
	 * @param time 格式为：
	 * @return
	 */
	public static Date stringToDate(String time) {

		if (KqStringUtils.isBlank(time)) {
			return null;
		}

		Date date = null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			date = sdf.parse(time);
			sdf = null;
		} catch (ParseException e) {

		}
		return date;
	}

	public static String firstDayOfWeek(Date time) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 设置时间格式
		Calendar cal = Calendar.getInstance();
		cal.setTime(time);
		// 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
		int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
		if (1 == dayWeek) {
			cal.add(Calendar.DAY_OF_MONTH, -1);
		}
		cal.setFirstDayOfWeek(Calendar.MONDAY);// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
		int day = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
		cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
		return sdf.format(cal.getTime());
	}

	/**
	 * 获取当前时间所在周的周一和周日的日期时间
	 * @return
	 */
	public static String lastDayOfWeek() {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		Calendar cal = Calendar.getInstance();
		// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
		cal.setFirstDayOfWeek(Calendar.MONDAY);
		// 获得当前日期是一个星期的第几天
		int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
		if(dayWeek==1){
			dayWeek = 8;
		}
		cal.add(Calendar.DATE, 4 +cal.getFirstDayOfWeek());
		Date sundayDate = cal.getTime();
		String weekEnd = sdf.format(sundayDate);

		return weekEnd;
	}

	public static String getFirstDayDateOfMonth(Date date) {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		Calendar cal = Calendar.getInstance();

		cal.setTime(date);

		int last = cal.getActualMinimum(Calendar.DAY_OF_MONTH);

		cal.set(Calendar.DAY_OF_MONTH, last);

		String day = sdf.format(cal.getTime());

		return day;
	}

	public static String getLastDayOfMonth(Date date) {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		final Calendar cal = Calendar.getInstance();

		cal.setTime(date);

		final int last = cal.getActualMaximum(Calendar.DAY_OF_MONTH);

		cal.set(Calendar.DAY_OF_MONTH, last);

		String day = sdf.format(cal.getTime());

		return day;

	}


	/**
	 * 获取当前日期所在的周一到周日的所有日期集合
	 * @return
	 */
	public static List<String> getWeekDateList() {
		Calendar cal = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
		cal.setFirstDayOfWeek(Calendar.MONDAY);
		// 获得当前日期是一个星期的第几天
		int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
		if(dayWeek==1){
			dayWeek = 8;
		}

		// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
		cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);
		Date mondayDate = cal.getTime();

		cal.add(Calendar.DATE, 4 +cal.getFirstDayOfWeek());
		Date sundayDate = cal.getTime();

		List<String> lDate = new ArrayList<String>();
		lDate.add(sdf.format(mondayDate));
		Calendar calBegin = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		calBegin.setTime(mondayDate);
		Calendar calEnd = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		calEnd.setTime(sundayDate);
		//测试此日期是否在指定日期之后
		while (sundayDate.after(calBegin.getTime())) {
			// 根据日历的规则，为给定的日历字段添加或减去指定的时间量
			calBegin.add(Calendar.DAY_OF_MONTH, 1);
			lDate.add(sdf.format(calBegin.getTime()));
		}
		return lDate;
	}


	public static List<String> getDayListOfMonth() {
		List<String> list = new ArrayList<String>();
		Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
		int year = aCalendar.get(Calendar.YEAR);//年份
		int month = aCalendar.get(Calendar.MONTH) + 1;//月份
		String monthStr = "";
		if (month < 10){
			monthStr = "0"+month;
		}
		int day = aCalendar.getActualMaximum(Calendar.DATE);
		for (int i = 1; i <= day; i++) {
			if (i < 10) {
				String aDate = String.valueOf(year) + "-" + monthStr + "-" + "0" +i;
				list.add(aDate);
			} else {
				String aDate = String.valueOf(year) + "-" + monthStr + "-" +i;
				list.add(aDate);
			}

		}
		return list;
	}

	/**
	 * 合并2个时间组装成一个区间 2022-1-14 11:00~12:00
	 *
	 * @param startDate 2022-1-14 11:00:00
	 * @param endDate   2022-1-14 12:00:00
	 * @return 2022-1-14 11:00-12:00
	 */
	public static String mergeDate(LocalDateTime startDate, LocalDateTime endDate) {
		return mergeDate(startDate, endDate, "-");
	}

	/**
	 * 合并2个时间组装成一个区间 2022-1-14 11:00~12:00
	 *
	 * @param startDate   2022-1-14 11:00:00
	 * @param endDate     2022-1-14 12:00:00
	 * @param mergeSymbol 合并的符号
	 * @return 2022-1-14 11:00-12:00
	 */
	public static String mergeDate(LocalDateTime startDate, LocalDateTime endDate, String mergeSymbol) {
		Assert.notNull(startDate, "none start date");
		Assert.notNull(endDate, "none start date");
		String startDateFormat = cn.hutool.core.date.DateUtil.format(startDate, DatePattern.NORM_DATETIME_MINUTE_PATTERN);
		String endDateFormat = cn.hutool.core.date.DateUtil.format(endDate, HH_MM);
		return startDateFormat + mergeSymbol + endDateFormat;
	}

	public static String formatBetween(Date beginDate, Date endDate, BetweenFormatter.Level level) {
		return formatBetween(between(beginDate, endDate, DateUnit.MS), level);
	}

	public static String formatBetween(Date beginDate, Date endDate) {
		return formatBetween(between(beginDate, endDate, DateUnit.MS));
	}

	public static String formatBetween(long betweenMs, BetweenFormatter.Level level) {
		return (new BetweenFormatter(betweenMs, level)).format();
	}

	public static String formatBetween(long betweenMs) {
		return (new BetweenFormatter(betweenMs, BetweenFormatter.Level.MILLISECOND)).format();
	}

	public static long between(Date beginDate, Date endDate, DateUnit unit) {
		return between(beginDate, endDate, unit, true);
	}

	public static long between(Date beginDate, Date endDate, DateUnit unit, boolean isAbs) {
		return (new DateBetween(beginDate, endDate, isAbs)).between(unit);
	}

}
